Skip to content

Feature/cstackex 265: Netapp ONTAP iscsi provisioning using lun serial number instead of logical unit number - #114

Merged
piyush5netapp merged 12 commits into
mainfrom
feature/CSTACKEX-265
Oct 14, 2026
Merged

piyush5netapp merged 12 commits into
mainfrom
feature/CSTACKEX-265

Conversation

@piyush5netapp

@piyush5netapp piyush5netapp commented Oct 8, 2026 •

Copy link
Copy Markdown

Description

This PR...

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

All provisioning workflows has been tested.
image
image
image
virsh domblklist i-2-73-VM
Target Source

vda /dev/disk/by-id/wwn-0x600a098078304d2d383f2f6b45734c63
vdb /dev/disk/by-id/wwn-0x600a098078304d2d383f2f6b45734c64
hdc -
hdd -
ls -la /dev/disk/by-id/
total 0
lrwxrwxrwx 1 root root 9 Oct 14 15:56 scsi-3600a098078304d2d383f2f6b45734c63 -> ../../sdc
lrwxrwxrwx 1 root root 10 Oct 14 15:56 scsi-3600a098078304d2d383f2f6b45734c63-part1 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Oct 14 15:56 scsi-3600a098078304d2d383f2f6b45734c63-part2 -> ../../sdc2
lrwxrwxrwx 1 root root 9 Oct 14 15:56 scsi-3600a098078304d2d383f2f6b45734c64 -> ../../sdd
lrwxrwxrwx 1 root root 9 Oct 14 15:56 wwn-0x600a098078304d2d383f2f6b45734c63 -> ../../sdc
lrwxrwxrwx 1 root root 10 Oct 14 15:56 wwn-0x600a098078304d2d383f2f6b45734c63-part1 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Oct 14 15:56 wwn-0x600a098078304d2d383f2f6b45734c63-part2 -> ../../sdc2
lrwxrwxrwx 1 root root 9 Oct 14 15:56 wwn-0x600a098078304d2d383f2f6b45734c64 -> ../../sdd

How did you try to break this feature and the system with this change?

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 24.74%
Branch coverage 18.86%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

OntapStorageConstants.SVM_DOT_NAME, svmName,
OntapStorageConstants.IGROUP_DOT_NAME, accessGroupName
);
String lunNumber = getLogicalAccess(getMap);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do change this code according to fetch the WWID instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, this change required a refactoring code changes in ontap plugin code as now logicalaccess is not lun number and we have some dead code change. https://netapp.atlassian.net/browse/CSTACKEX-349

*
* @return the serial number, or null if the LUN no longer exists on the array
*/
public String getLunSerialNumber(String svmName, String lunName) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method might not be needed, as earlier LUN was fetched in ensureLunMapped, so the same implementation would be present there. Just change the query param accordingly.

@piyush5netapp piyush5netapp Oct 14, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as https://netapp.atlassian.net/browse/CSTACKEX-349. Also , lun-map API does not return lun serial number and we need to call get Lun API.

/**
* NetApp's IEEE OUI, which prefixes the NAA identifier of every ONTAP LUN.
*
* <p>A LUN's WWID is this followed by the hex of its 12-character serial number, giving the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to restrict the explanation to 1-2 lines highlighting the structure of the path

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

@Override
public boolean zoneWideVolumesAvailableWithoutClusterMotion(){

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe its better to raise a separate PR for this, as we would be cherry-picking the commits for upstream

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed in planning meeting, Piyush will take this change to upstream and add the compute to compute testing details also

*
* So {@code OntapPrimaryDatastoreDriver} writes volume paths as {@code /<targetIQN>/<lunWwid>} and
* this adaptor reports devices as {@code /dev/disk/by-id/scsi-3<lunWwid>}. The WWID is derived from
* the LUN's own inquiry data (VPD page 0x83), so it is identical on every host and the domain XML

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of this comment may not be necessary for future, so, consider pruning this to explain the adaptor in brief, instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* udev's scsi_id builtin prepends the NAA designator type to the WWID, so a LUN whose WWID is
* {@code 600a0980...} is published as {@code scsi-3600a0980...}.
*/
private static final String BY_ID_SCSI_PREFIX = "/dev/disk/by-id/scsi-3";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future reference, add a comment here or in our spec that /dev/disk/by-id/scsi-3 is set here as ONTAP uses NAA and 600a098... is the NetApp OUI vendor prefix 00:a0:98

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return null;
}

private boolean createIscsiNode(String host, int port, String iqn, String volumePath) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add null checks for all the variables

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iscsi session will throw error and it is handled automatically.

KVMStoragePool destPool, int timeout, byte[] passphrase) {
throw new UnsupportedOperationException("Creating a disk from a template is not yet supported for this configuration.");
private void waitForDeviceToDisappear(String devicePath) {
for (int attempt = 0; attempt < DEVICE_WAIT_TRIES && getDeviceSize(devicePath) > 0; attempt++) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for 15s wait period for devices to respond everywhere in this file? Or was this pulled in from iSCSIAdmAdaptor?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its just a cushion time.And yes it was pulled from iscsi adapter

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could u run this command
udevadm info -q symlink -n /dev/sdb
will this show both forms in that output (Id and path )?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

udevadm info -q symlink -n /dev/sdc
disk/by-id/scsi-3600a098078304d2d383f2f6b45734c2f disk/by-id/wwn-0x600a098078304d2d383f2f6b45734c2f disk/by-path/ip-10.196.37.157:3260-iscsi-iqn.1992-08.com.netapp:sn.45048fd9b65111f1b106005056bd83cf:vs.3-lun-0.

@suryag1201 suryag1201 Oct 14, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is still showing this bcz udev created with lun number also? So, it is fine?
disk/by-path/ip-10.196.37.157:3260-iscsi-iqn.1992-08.com.netapp:sn.45048fd9b65111f1b106005056bd83cf:vs.3-lun-0


@Override
public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) {
public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check this method: IscsiStorageCleanupMonitor, this used by-path param and if not exact match then iSCSI cleanup thread will log out live ONTAP sessions

@piyush5netapp piyush5netapp Oct 14, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not support iscsi clean flag = true for Netapp ONTAP.


// ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new
Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger);
if (!createIscsiNode(host, port, iqn, volumePath)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perform this test also, when 2 VMs are running and if u stop 1 VM what happens?
does this logout the whole session ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, whole session is not removed.


physicalDisk.setSize(deviceSize);
physicalDisk.setVirtualSize(deviceSize);
if (!logoutAndForgetTarget(host, port, iqn, lunWwid)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the session cannot be identified, do not log out. Remove only this SCSI device, or fail the disconnect so it can be retried. Logout should run only after the session is known and no other LUNs remain on it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. taken care.

* Must remain in {@code com.cloud.hypervisor.kvm.storage}: {@link KVMStoragePoolManager}
* discovers adaptors only in that package. An unregistered type falls back to
* {@link LibvirtStorageAdaptor}.
* Serves {@link StoragePoolType#OntapiSCSI} pools: ONTAP FlexVols exposed over iSCSI with one LUN

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for the comment reframing

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

* Anchoring on the prefix is what stops this adaptor claiming another vendor's scsi-3 device
* when KVMStoragePoolManager.disconnectPhysicalDiskByPath scans every adaptor.
*/
private static final Pattern LUN_WWID = Pattern.compile("600a0980[0-9a-f]{24}");

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make Netapp OUI as a constant.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

OntapStorageConstants.SVM_DOT_NAME, svmName,
OntapStorageConstants.IGROUP_DOT_NAME, accessGroupName
);
String lunNumber = getLogicalAccess(getMap);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, this change required a refactoring code changes in ontap plugin code as now logicalaccess is not lun number and we have some dead code change. https://netapp.atlassian.net/browse/CSTACKEX-349

*
* @return the serial number, or null if the LUN no longer exists on the array
*/
public String getLunSerialNumber(String svmName, String lunName) {

@piyush5netapp piyush5netapp Oct 14, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as https://netapp.atlassian.net/browse/CSTACKEX-349. Also , lun-map API does not return lun serial number and we need to call get Lun API.

/**
* NetApp's IEEE OUI, which prefixes the NAA identifier of every ONTAP LUN.
*
* <p>A LUN's WWID is this followed by the hex of its 12-character serial number, giving the

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

udevadm info -q symlink -n /dev/sdc
disk/by-id/scsi-3600a098078304d2d383f2f6b45734c2f disk/by-id/wwn-0x600a098078304d2d383f2f6b45734c2f disk/by-path/ip-10.196.37.157:3260-iscsi-iqn.1992-08.com.netapp:sn.45048fd9b65111f1b106005056bd83cf:vs.3-lun-0.


@Override
public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) {
public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details, boolean isVMMigrate) {

@piyush5netapp piyush5netapp Oct 14, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not support iscsi clean flag = true for Netapp ONTAP.


// ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new
Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger);
if (!createIscsiNode(host, port, iqn, volumePath)) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, whole session is not removed.


physicalDisk.setSize(deviceSize);
physicalDisk.setVirtualSize(deviceSize);
if (!logoutAndForgetTarget(host, port, iqn, lunWwid)) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. taken care.

@github-actions

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 24.85%
Branch coverage 19.01%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@github-actions

Copy link
Copy Markdown

🔴 Test Coverage Grade: D — Marginal

Metric Value
Line coverage 24.85%
Branch coverage 19.01%

Grade Scale

Grade Line Coverage Meaning
🟢 A ≥ 80% Excellent - this code sleeps well at night 😴
🟡 B 60-79% Good - almost there, don't stop now 😉
🟠 C 40-59% Acceptable - your code is wearing a seatbelt, but no airbags 😬
🔴 D 20-39% Marginal - boldly shipping where no test has gone before 🖖
⛔ F < 20% Failing - tests? what tests? 🔥

Branch coverage is shown as a secondary signal. Grade is determined by line coverage.
View full Actions run

@piyush5netapp
piyush5netapp merged commit e2a2682 into main Oct 14, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants